package org.dreamwork.jasmine2.web.controls.chart.settings.template;

import org.dreamwork.jasmine2.template.impl.BaseTemplate;
import org.dreamwork.jasmine2.web.controls.chart.settings.ChartSetting;
import org.dreamwork.jasmine2.web.controls.chart.settings.ChartSettingAttribute;
import org.dreamwork.jasmine2.web.controls.chart.settings.ChartSettingSection;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Created by IntelliJ IDEA.
 * User: seth
 * Date: 2010-5-12
 * Time: 10:29:00
 */
public abstract class ChartTemplate extends BaseTemplate {
    protected abstract ChartSetting initChartSetting ();

    public ChartSetting buildChartSetting () {
        NodeList list = root.getChildNodes ();
        ChartSetting setting = initChartSetting ();
        for (int i = 0; i < list.getLength (); i ++) {
            Element e = (Element) list.item (i);
            if (isSectionNode (e)) buildChartSection (setting, e);
            else buildChartAttribute (setting, e);
        }

        return setting;
    }

    private void buildChartSection (ChartSettingSection css, Element e) {
        ChartSettingSection section = css.addSection (e.getNodeName (), true);
        NamedNodeMap map = e.getAttributes ();
        for (int i = 0; i < map.getLength (); i ++) {
            Node n = map.item (i);
            section.setProperty (n.getNodeName (), n.getNodeValue ());
        }
        NodeList list = e.getChildNodes ();
        for (int i = 0; i < list.getLength (); i ++) {
            Element element = (Element) list.item (i);
            if (isSectionNode (element)) buildChartSection (section, element);
            else buildChartAttribute (section, element);
        }
    }

    private void buildChartAttribute (ChartSettingSection css, Element e) {
        Node node = e.getFirstChild ();
        ChartSettingAttribute csa = new ChartSettingAttribute (e.getNodeName (), node.getNodeValue ());
        NamedNodeMap map = e.getAttributes ();
        for (int i = 0; i < map.getLength (); i ++) {
            Node n = map.item (i);
            csa.setProperty (n.getNodeName (), n.getNodeValue ());
        }
        csa.setXmlCddata (node.getNodeType () == Node.CDATA_SECTION_NODE);
        css.addAttribute (csa, true);
    }

    private boolean isSectionNode (Element e) {
        NodeList list = e.getChildNodes ();
        if (list.getLength () == 1) {
            Node first = e.getFirstChild ();
            short type = first.getNodeType ();
            return type != Node.TEXT_NODE && type != Node.CDATA_SECTION_NODE;
        } else {
            for (int i = 0; i < list.getLength (); i ++) {
                Node node = list.item (i);
                if (node.getNodeType () == Node.ELEMENT_NODE) return true;
            }
            return false;
        }
    }
}